﻿using DDTek.Oracle;
using Excel2DbTool.Common;
using Excel2DbTool.Helpers;
using Excel2DbTool.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Excel2DbTool.Migrater_New
{

    public abstract class SimpleDbTableMigrater
    {
        protected abstract IList<DbFieldMapping> DbFieldMappings { get; }

        public String GetFieldStringNeedReslove()
        {
            IEnumerable<String> orignFieldNames = DbFieldMappings.Where(dbfm => dbfm.OrignFieldName != OrginTableFieldNames.NONE)
                                                                .Select(dbfm => dbfm.OrignFieldName)
                                                                .ToList();
            return string.Join(",", orignFieldNames);
        }


        public String GetFieldStringNeedInsert()
        {
            IEnumerable<String> targetFieldNames = DbFieldMappings.Select(dbfm => dbfm.TargetFieldName).ToList();
            return string.Join(",", targetFieldNames);
        }

    }


    public abstract class SimpleDbTableTransactionMigrater : SimpleDbTableMigrater
    {
        protected Action<string> GetTransactionInsertFunc(OracleCommand commandHasSetted)
        {

            Action<string> implement = (sql) =>
            {
                try
                {
                    if (string.IsNullOrEmpty(sql))
                    {
                        return;
                    }

                    commandHasSetted.CommandText = sql;
                    commandHasSetted.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    string errorMsg = string.Format("{0}+:+{1}",ex.Message,sql);
                    throw new Excel2DbException(errorMsg, ex);
                }
            };

            return implement;
        }

        protected sealed class DbTableMigraterManager
        {
            public static void Execute(IEnumerable<string> insertSqlStrings)
            {
                OracleCommand command = GetOracleCommand();
                Action<string> insertAction = GetTransactionInsertFunc(command);

                try
                {
                    foreach (var sqlStr in insertSqlStrings)
                    {
                        insertAction(sqlStr);
                    }
                }
                catch (Excel2DbException ex)
                {
                    command.Transaction.Rollback();
                    throw;
                }
                finally
                {
                    command.Connection.Close();
                    command.Dispose();
                }
            }

            static OracleCommand GetOracleCommand()
            {
                OracleConnection myConnection = new OracleConnection(ConfigHelper.DbConnectStr);
                myConnection.Open();

                OracleCommand command = new OracleCommand();

                OracleTransaction myTrans = myConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);

                command.Transaction = myTrans;
                command.Connection = myConnection;

                return command;
            }

            static Action<string> GetTransactionInsertFunc(OracleCommand commandHasSetted)
            {

                Action<string> implement = (sql) =>
                {
                    try
                    {
                        commandHasSetted.CommandText = sql;
                        commandHasSetted.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        throw new Excel2DbException(ex.Message, ex);
                    }
                };

                return implement;
            }
        }
    }
}
